package com.clothing.customization.service.impl;

import com.clothing.customization.entity.ImageFile;
import com.clothing.customization.repository.ImageFileRepository;
import com.clothing.customization.service.ImageFileService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

/**
 * 图片文件服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ImageFileServiceImpl implements ImageFileService {
    
    private final ImageFileRepository imageFileRepository;
    
    @Value("${file.upload.path:uploads}")
    private String uploadPath;
    
    @Value("${file.upload.access-path:/uploads}")
    private String accessPath;
    
    @Value("${server.port:8083}")
    private String serverPort;
    
    /**
     * 上传图片文件
     *
     * @param file       上传的文件
     * @param module     模块名称
     * @param relationId 关联ID
     * @return 图片文件对象
     */
    @Override
    @Transactional
    public ImageFile uploadImage(MultipartFile file, String module, Long relationId) {
        try {
            // 转换为绝对路径
            String absolutePath;
            if (uploadPath.startsWith("./") || !uploadPath.startsWith("/")) {
                // 获取当前工作目录
                String userDir = System.getProperty("user.dir");
                Path path = Paths.get(userDir, uploadPath.replace("./", ""));
                absolutePath = path.toAbsolutePath().toString();
            } else {
                absolutePath = uploadPath;
            }
            
            log.info("使用上传目录: {}", absolutePath);
            
            // 确保上传目录存在
            Path uploadDir = Paths.get(absolutePath);
            if (!Files.exists(uploadDir)) {
                Files.createDirectories(uploadDir);
                log.info("创建上传根目录: {}", uploadDir);
            }
            
            // 创建按日期分类的子目录
            String dateDir = new SimpleDateFormat("yyyyMMdd").format(new Date());
            Path dateDirPath = Paths.get(absolutePath, dateDir);
            if (!Files.exists(dateDirPath)) {
                Files.createDirectories(dateDirPath);
                log.info("创建日期目录: {}", dateDirPath);
            }
            
            // 获取文件名和扩展名
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null || originalFilename.isEmpty()) {
                originalFilename = "unknown_file";
            }
            
            String extension = "";
            int dotIndex = originalFilename.lastIndexOf(".");
            if (dotIndex >= 0) {
                extension = originalFilename.substring(dotIndex);
            }
            
            // 生成新的文件名
            String newFilename = UUID.randomUUID().toString() + extension;
            
            // 保存文件
            Path destFile = dateDirPath.resolve(newFilename);
            log.info("保存文件到: {}", destFile);
            
            // 检查文件是否已存在，如果存在则先删除
            if (Files.exists(destFile)) {
                log.warn("文件已存在，将被覆盖: {}", destFile);
                Files.delete(destFile);
            }
            
            Files.copy(file.getInputStream(), destFile);
            
            // 文件相对路径
            String relativePath = dateDir + "/" + newFilename;
            
            // 构建文件访问URL
            String fileUrl = accessPath.replace("/**", "") + "/" + relativePath;
            log.info("文件访问URL: {}", fileUrl);
            
            // 创建图片文件记录
            ImageFile imageFile = ImageFile.builder()
                    .originalFilename(originalFilename)
                    .storedFilename(newFilename)
                    .contentType(file.getContentType())
                    .fileSize(file.getSize())
                    .filePath(relativePath)
                    .accessUrl(fileUrl)
                    .createdTime(LocalDateTime.now())
                    .module(module)
                    .relationId(relationId)
                    .build();
            
            // 保存图片文件记录
            return imageFileRepository.save(imageFile);
        } catch (IOException e) {
            log.error("上传图片失败", e);
            throw new RuntimeException("上传图片失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 获取图片文件信息
     *
     * @param id 图片ID
     * @return 图片文件对象
     */
    @Override
    public ImageFile getImageById(Long id) {
        return imageFileRepository.findById(id).orElse(null);
    }
    
    /**
     * 根据模块和关联ID获取图片列表
     *
     * @param module     模块名称
     * @param relationId 关联ID
     * @return 图片文件列表
     */
    @Override
    public List<ImageFile> getImagesByModuleAndRelationId(String module, Long relationId) {
        return imageFileRepository.findByModuleAndRelationId(module, relationId);
    }
    
    /**
     * 删除图片文件
     *
     * @param id 图片ID
     * @return 是否删除成功
     */
    @Override
    @Transactional
    public boolean deleteImage(Long id) {
        Optional<ImageFile> imageOptional = imageFileRepository.findById(id);
        if (imageOptional.isPresent()) {
            ImageFile image = imageOptional.get();
            
            // 获取绝对路径
            String absolutePath;
            if (uploadPath.startsWith("./") || !uploadPath.startsWith("/")) {
                String userDir = System.getProperty("user.dir");
                Path path = Paths.get(userDir, uploadPath.replace("./", ""));
                absolutePath = path.toAbsolutePath().toString();
            } else {
                absolutePath = uploadPath;
            }
            
            // 删除物理文件
            try {
                Path filePath = Paths.get(absolutePath, image.getFilePath());
                log.info("尝试删除文件: {}", filePath);
                Files.deleteIfExists(filePath);
            } catch (IOException e) {
                log.error("删除文件失败: {}", image.getFilePath(), e);
                return false;
            }
            
            // 删除数据库记录
            imageFileRepository.delete(image);
            return true;
        }
        return false;
    }
} 